#include "StdFile.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define true 1
#define false 0
#define LineSize 100

int IsFileExist(const char *FilePath)
{
    FILE *file = fopen(FilePath, "r");
    if (file == NULL)
    {
        return false;
    }
    fclose(file);
    return true;
}

char *LoadFromFile(const char *FilePath)
{
    FILE *file = fopen(FilePath, "r");
    if (file == NULL)
    {
        printf("loadFromFile open file error\n");
        return NULL;
    }

    fseek(file, 0, SEEK_END);  // 指向文本文档末尾
    size_t size = ftell(file); // 光标位置即整个文本内的字节数

    char *str = (char *)malloc(size + 1); // 开空间加一给'\0'
    if (str == NULL)
    {
        printf("loadFromFile malloc error\n");
        return NULL;
    }

    fseek(file, 0, SEEK_SET); // 指向开头
    fread(str, size, 1, file);
    str[size] = '\0'; // 给结尾手动填上‘\0’

    fclose(file);
    return str;
}

int GetFileSize(const char *FilePath)
{
    FILE *file = fopen(FilePath, "r");
    if (file == NULL)
    {
        printf("loadFromFile open file error\n");
        return 0;
    }

    fseek(file, 0, SEEK_END);  // 指向文本文档末尾
    size_t size = ftell(file); // 光标位置即整个文本内的字节数
    return size + 1;
}

void RemoveCharByIndex(char *a, int index)
{
    if (index < 0 || index >= strlen(a))
    {
        printf("RemoveIndex error\n");
        return;
    }
    for (int i = index; i < strlen(a); i++)
    {
        a[i] = a[i + 1];
    }
}

void RemoveCharByElement(char *a, char element)
{
    int len = strlen(a);
    for (int i = 0; i < len; i++)
    {
        if (a[i] == element)
        {
            RemoveCharByIndex(a, i);
            i = i - 1;
        }
    }
}

DLlist *GetLineFromFile(const char *FILEPath)
{
    FILE *file = fopen(FILEPath, "r");
    if (file == NULL)
    {
        printf("GetLineFromFile open file error\n");
        return NULL;
    }

    DLlist *list = (DLlist *)malloc(sizeof(DLlist));
    if (list == NULL)
    {
        printf("GetLineFromFile malloc error\n");
        return NULL;
    }
    InitDLlist(list);
    char LineContent[LineSize] = {0};
    while (fgets(LineContent, LineSize, file) != NULL)
    {
        char *line = (char *)malloc(strlen(LineContent) + 1); // 多一个位置留给'\0'
        strcpy(line, LineContent);                            // strcpy会在复制完目标文件后自动加'\0'
        RemoveCharByElement(line, '\n');                      // 去掉字符串中的换行
        InsertTail(list, line);                               // 尾差法
    }
    fclose(file);
    return list;
}

void Print(ElementType element) // 回调打印函数
{
    char *str1 = (char *)element;
    printf("%s\n", str1);
}

void ChooseLineToPrint(const char *FilePath, int line, void (*func)(ElementType)) // 打印文件中某行元素
{

    DLlist *list = GetLineFromFile(FilePath);
    TravelDLlist(list, Print);

    struct Node *travelPoint = list->head; // 遍历指针
    while (line != 1)
    {
        travelPoint = travelPoint->next;
        line--;
    }
    func(travelPoint->data); // 打印
}

void WriteToFile(const char *FilePath, void *ptr, size_t size) // 将字符串写进文件
{
    FILE *file = fopen(FilePath, "w");
    if (file == NULL)
    {
        printf("writeToFile open file error\n");
        return;
    }

    strcat(ptr, "/0");
    if (fwrite(ptr, size, 1, file) <= 0)
    {
        printf("writeToFile error\n");
    }

    fclose(file);
}

void WriteLineToFile(const char *FilePath, DLlist *list)
{
    FILE *file = fopen(FilePath, "w");
    if (file == NULL)
    {
        printf("WriteLineToFile open file error\n");
        return;
    }
    struct Node *travelPoint = list->head;
    while (travelPoint != NULL)
    {
        char *temp = (char *)travelPoint->data;
        fputs(temp, file);
        fputc('\n', file);
        travelPoint = travelPoint->next;
    }
    fclose(file);
}

void CopyFile(const char *SourcePath, const char *TargetPath)
{
    if (IsFileExist(SourcePath) == false)
    {
        printf("the sourcefile is not exist or has no read permission\n");
        return;
    }

    char *fileContent = LoadFromFile(SourcePath); // 将原文件的内容全部输出到fileContent中
    if (IsFileExist(TargetPath) == true)
    {
        char TargetName[100] = {0}; // 新建一个字符数组，用于分割
        strcpy(TargetName, TargetPath);

        char *fileName = strtok(TargetName, ".");
        char *backName = strtok(NULL, ".");

        char newName[100] = {0};
        strcpy(newName, fileName);
        strcat(newName, "_new.");
        strcat(newName, backName);

        printf("%s", newName);
        if (IsFileExist(newName) == true)
        {
            CopyFile(SourcePath, newName);
            return;
        }
        WriteToFile(newName, fileContent, strlen(fileContent));
        free(fileContent);
        return;
    }
    WriteToFile(TargetPath, fileContent, strlen(fileContent));
    free(fileContent);
}

void AppendToFile(const char *FilePath, void *ptr, size_t size)
{
    FILE *file = fopen(FilePath, "a");
    if (file == NULL)
    {
        printf("AppendToFile open file error");
        return;
    }
    fwrite(ptr, size, 1, file);
    fclose(file);
}

void MakeDir1(const char *name)
{
    char sql[1024] = {0};
    sprintf(sql, "mkdir ./FileLibrary/%s", name);
    system(sql);
}

void MakeDir2(const char *name)
{
    char sql[1024] = {0};
    sprintf(sql, "mkdir ./Group/GroupFile/%s", name);
    system(sql);
}